package com.legal.service.user.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.legal.domain.dto.LoginFormDTO;
import com.legal.domain.dto.RegisterFormDTO;
import com.legal.domain.po.User;
import com.legal.domain.vo.UserLoginVO;
import com.legal.domain.vo.UserRegisterVO;
import com.legal.enums.CaptchaExceptionMsgEnums;
import com.legal.enums.RegisterExceptionMsgEnums;
import com.legal.enums.UserExceptionMsgEnums;
import com.legal.enums.UserStatus;
import com.legal.exception.CaptchaException;
import com.legal.exception.RegisterException;
import com.legal.exception.UserException;
import com.legal.mapper.UserMapper;
import com.legal.service.user.CaptchaService;
import com.legal.service.user.IUserService;
import com.legal.utils.BeanUtil;
import com.legal.utils.JwtUtils;
import com.legal.utils.NoUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

/**
 * @author xiaopeng
 * @version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final CaptchaService captchaService;

    // 默认用户头像
    private final static String avatarUrl = "https://lkw-bucket.oss-cn-chengdu.aliyuncs.com/ai-assistant/avater-cat.jpeg";

    private final PasswordEncoder passwordEncoder;

    @Override
    public UserLoginVO login(LoginFormDTO loginDTO) {
        // 1.数据校验
        String account = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        // 2.根据用户名或手机号查询
        User user = lambdaQuery().eq(User::getUserAccount, account).one();
        if (user == null) {
            // 用户不存在
            //throw new CommonException(CommonExceptionEnums.USER_NOT_EXIST);
            throw new UserException(UserExceptionMsgEnums.USER_NOT_EXIST);
        }
        // 3.校验是否停用
        if (user.getAccountStatus() == UserStatus.FROZEN.getValue() ||
                user.getIsEnabled() == UserStatus.FROZEN.getValue()) {
            //throw new CommonException(CommonExceptionEnums.USER_LOCKED);
            throw new UserException(UserExceptionMsgEnums.USER_LOCKED);
        }
        // 4.校验密码
        if (!passwordEncoder.matches(password, user.getPasswordHash())) {
            //throw new CommonException(CommonExceptionEnums.LOGIN_ERR);
            throw new UserException(UserExceptionMsgEnums.LOGIN_ERR);
        }

        // 5.生成token
        //登录成功,生成令牌,下发令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("user_no", user.getUserNo());
        claims.put("isAdmin", user.getIsAdmin());
        claims.put("user_account", user.getUserAccount());

        String token = JwtUtils.generateJwt(claims); //jwt包含了当前登录的用户信息

        // 6.封装VO返回
        UserLoginVO vo = new UserLoginVO();
        vo.setUserNo(user.getUserNo());
        vo.setUsername(user.getUserAccount());
        vo.setToken(token);
        vo.setIsAdmin(user.getIsAdmin());
        vo.setAvatar(user.getAvatarUrl());

        return vo;
    }

    @Override
    @Transactional
    public UserRegisterVO register(RegisterFormDTO registerDTO) {
        // 1.校验手机号是否已经存在
        if (!CheckPhoneNumber(registerDTO.getPhoneNumber())) {
            //throw new CommonException(CommonExceptionEnums.PHONE_NUMBER_EXIST);
            throw new RegisterException(RegisterExceptionMsgEnums.PHONE_NUMBER_EXIST);
        }
        // 检查用户名是否已经存在
        if (!CheckUserNameExist(registerDTO.getUsername())) {
            //throw new CommonException(CommonExceptionEnums.USERNAME_NUMBER_EXIST);
            throw new RegisterException(RegisterExceptionMsgEnums.USERNAME_NUMBER_EXIST);
        }
        // 2.校验验证码
        String phoneNumber = registerDTO.getPhoneNumber();
        String inputCode = registerDTO.getCaptcha();
        if (inputCode == null || !captchaService.validateCaptcha(phoneNumber, inputCode)) {
            //throw new CommonException(CommonExceptionEnums.CAPTCHA_ERROR);
            throw new CaptchaException(CaptchaExceptionMsgEnums.CAPTCHA_INVALID);
        }

        // 保存用户信息
        User user = new User();
        user.setUserAccount(registerDTO.getUsername());
        user.setPasswordHash(passwordEncoder.encode(registerDTO.getPassword()));
        user.setPhoneNumber(registerDTO.getPhoneNumber());
        String no = NoUtils.GetNo("US"); // 根据时间生成唯一用户编号
        user.setUserNo(no);
        user.setNickname("user" + no.substring(7));
        user.setAvatarUrl(avatarUrl); // 默认头像
        save(user); // 保存用户信息

        // 删除验证码
        captchaService.deleteCaptcha(registerDTO.getPhoneNumber());

        return BeanUtil.copy(user, UserRegisterVO.class);
    }

    /**
     * 校验手机号是否已经存在
     *
     * @param phoneNumber
     * @return
     */
    @Transactional
    public Boolean CheckPhoneNumber(String phoneNumber) {
        User u = lambdaQuery().eq(User::getPhoneNumber, phoneNumber).one();
        return u == null;
    }

    /**
     * 检验用户名是否已经存在
     *
     * @param username
     * @return
     */
    @Transactional
    public Boolean CheckUserNameExist(String username) {
        User u = lambdaQuery().eq(User::getUserAccount, username).one();
        return u == null;
    }
}
